﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using HtmlAgilityPack;

namespace WindowsFormsApp1
{
    public partial class DownImagesForm : Form
    {
        public DownImagesForm()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //验证
            int Bnum = 2;
            int Enum = 0;
            if (!int.TryParse(txb_BNum.Text.Trim(), out Bnum))
            {
                MessageBox.Show("数值不正确");
                return;
            }
            if (!int.TryParse(txb_num.Text.Trim(), out Enum))
            {
                MessageBox.Show("数值不正确");
                return;
            }

            if (Bnum > Enum)
            {
                MessageBox.Show("开始数值不能大于结束数值");
                return;
            }

          
            string xpath = txb_xpath.Text.Trim();
            string downPath = txb_downPath.Text.Trim();
            if (txb_rule.Text.Trim().Length == 0)
            {
                MessageBox.Show("增量页规则必须填");
                return;
            }

            if (xpath.Length == 0)
            {
                MessageBox.Show("xpath必须填");
                return;
            }
            if (downPath.Length == 0)
            {
                MessageBox.Show("下载地址必须填");
                return;
            }

            var pageList = txb_rule.Text.Replace(System.Environment.NewLine, "|").Split('|');

            int num = 0;
            foreach (var homePage in pageList)
            {
                if (!homePage.Contains("{0}"))//单页
                {
                    if(DownLoadImage(string.Format(homePage, string.Empty), xpath, downPath) ) num++ ;
                }
                else //多页批量下载
                {
                    string replaceStr = txb_replace.Text.Trim();
                    if (replaceStr.Length == 0)
                    {
                        MessageBox.Show("拼接内容需要填写");
                        return;
                    }

                    if (DownLoadImage(string.Format(homePage, string.Empty), xpath, downPath))//首页有内容才可以继续
                    {
                        string tempimgUrl;
                        for (int i = Bnum; i <= Enum; i++)
                        {
                            tempimgUrl = string.Format(homePage, replaceStr.Replace("[num]", i.ToString()));
                            if (!DownLoadImage(tempimgUrl, xpath, downPath))//下载完成了
                            {
                                num++;
                                break;
                            }
                        }

                    }
                }

            }

            MessageBox.Show("完成下载"+num+"/"+ pageList.Length);
        }

        private static bool DownLoadImage(string url,string xpath,string saveBaseDir)
        {
            try
            {
                var html = HttpGET(url);
                if (!html.Item2) return false;//请求的页面和显示页面不同
                if (string.IsNullOrEmpty(html.Item1)) return false;

                //解析
                HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
                doc.LoadHtml(html.Item1);
                HtmlNodeCollection imgNodes = doc.DocumentNode.SelectNodes(xpath);

                List<DownLoadFileBllcs.ATLRLAttachment> imgList = new List<DownLoadFileBllcs.ATLRLAttachment>();
                if (imgNodes != null)
                {
                    if (!Directory.Exists(saveBaseDir))
                    {
                        Directory.CreateDirectory(saveBaseDir); //在根目录下建立文件夹
                    }

                    string src;
                    string extensionName;//后缀名称
                    DownLoadFileBllcs.ATLRLAttachment tempImg;
                    for (int i = 0; i < imgNodes.Count; i++)
                    {
                        if (imgNodes[i].Attributes["src"] != null)
                        {
                            src = imgNodes[i].Attributes["src"].Value.Split('?')[0];//去掉url后面随机数 ?id=123
                            extensionName = DownLoadFileBllcs.GetExtension(src);

                            //svg格式下载有问题，暂不支持svg下载
                            if (!string.IsNullOrEmpty(src) && extensionName.ToLower() != "svg")
                            {
                                tempImg = new DownLoadFileBllcs.ATLRLAttachment();
                                //tempImg.FileContent = UrlToImage(src);
                                tempImg.ExtensioName = extensionName.Length == 0 ? "jpg" : extensionName;
                                tempImg.src = src;
                                imgList.Add(tempImg);
                            }
                        }
                    }

                    //下载图片
                    foreach (var img in imgList)
                    {
                        FileDownLoad(img,saveBaseDir);
                    }

                }
                else //没有获取到指定的图片
                {
                    return false;
                }

                return true;
            }
            catch (Exception ex)
            {
                return false;
            }

        }

        private static void FileDownLoad(DownLoadFileBllcs.ATLRLAttachment attachment, string saveBaseDir)
        {
            //https://www.images.zflpic.vip:8819/allimg/190726/2212244Q6-4.jpg 图片地址

            //获取 www.images.zflpic.vip:8819/allimg/190726/2212244Q6-4.jpg
            string srcUrl = attachment.src
                .Split('?')[0]
                .Split('#')[0]
                .Replace("https://", "")
                .Replace("http://", "")
                .Replace(":","_");//去掉端口号符号

            var srcTempList = srcUrl.Split('/');

            StringBuilder sb = new StringBuilder(saveBaseDir);
            for (int i = 0; i < srcTempList.Length-1; i++)
            {
                sb.Append("\\" + srcTempList[i]);
            }
            string divPath = sb.ToString();
            if (!Directory.Exists(divPath))
            {
                Directory.CreateDirectory(divPath); //在根目录下建立文件夹
            }

            try
            {
                WebRequest request = WebRequest.Create(attachment.src);
                WebResponse response = request.GetResponse();
                Stream reader = response.GetResponseStream();
                FileStream writer = new FileStream(divPath+"\\"+ srcTempList[srcTempList.Length-1], FileMode.OpenOrCreate, FileAccess.Write);
                byte[] buff = new byte[512];
                int c = 0; //实际读取的字节数
                while ((c = reader.Read(buff, 0, buff.Length)) > 0)
                {
                    writer.Write(buff, 0, c);
                }
                writer.Close();
                writer.Dispose();
                reader.Close();
                reader.Dispose();
                response.Close();
            }
            catch (Exception ex)
            {

            }
        }

        /// <summary>
        /// GET请求
        /// </summary>
        /// <param name="GETURL"></param>
        /// <returns></returns>
        private static (string,bool) HttpGET(string GETURL)
        {
            TcpClientHttpRequest hr = new TcpClientHttpRequest();
            hr.Action = GETURL;
            //hr.Method = "get"; //默认
            hr.Send();

            string requestUrl = GETURL
                .Split('?')[0]
                .Split('#')[0]
                .Replace("https://", "")
                .Replace("http://", "");

            string responsUrl = hr.Response.Action
                .Split('?')[0]
                .Split('#')[0]
                .Replace("https://", "")
                .Replace("http://", "");


            return (hr.Response.Xml, requestUrl== responsUrl);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            //筛选下载地址
            //验证
            int Bnum = 2;
            int Enum = 0;
            if (!int.TryParse(txb_linkeBNum.Text.Trim(), out Bnum))
            {
                MessageBox.Show("数值不正确");
                return;
            }
            if (!int.TryParse(txb_linkNum.Text.Trim(), out Enum))
            {
                MessageBox.Show("数值不正确");
                return;
            }

            if (Bnum > Enum)
            {
                MessageBox.Show("开始数值不能大于结束数值");
                return;
            }

            string xpath = txb_linkXpath.Text.Trim();
            string homeUrl = txb_linkUrl.Text.Trim();
            if (homeUrl.Length == 0)
            {
                MessageBox.Show("列表地址必须填");
                return;
            }

            if (xpath.Length == 0)
            {
                MessageBox.Show("获取链接的xpath");
                return;
            }
            else if(!xpath.Contains("/a"))
            {
                MessageBox.Show("xpath不含有a标签，是无效的");
                return;
            }


            var linkInfo = GetLink(string.Format(homeUrl,string.Empty), xpath);
            string tempimgUrl;
            if (linkInfo.Item2)//首页成功
            {
                string replaceStr = txb_linkReplace.Text.Trim();
                if (replaceStr.Length > 0)//需要获取分页，分页后再获取多个链接
                {
                    StringBuilder sb = new StringBuilder(linkInfo.Item1);
                    for (int i = Bnum; i <= Enum; i++)
                    {
                        tempimgUrl = string.Format(homeUrl, replaceStr.Replace("[num]", i.ToString()));
                        linkInfo = GetLink(tempimgUrl, xpath);
                        if (!linkInfo.Item2)//有异常说明没有分页信息了
                        {
                            txb_rule.Text =sb.ToString();
                            break;
                        }
                        else
                        {
                            sb.AppendLine(linkInfo.Item1);
                        }
                    }
                    txb_rule.Text = sb.ToString();

                }
                else
                {
                    txb_rule.Text = linkInfo.Item1;
                }
                
            }
            else
            {
                MessageBox.Show(linkInfo.Item1);
            }
        }

        private static (string,bool) GetLink(string url,string xpath)
        {
            var html = HttpGET(url);

            if (!html.Item2)
            {
                return ("页面已经超出指定", false);
            }

            //解析
            HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
            doc.LoadHtml(html.Item1);
            HtmlNodeCollection linkNodes = doc.DocumentNode.SelectNodes(xpath);
            if (linkNodes != null)
            {
                try
                {
                    StringBuilder sb = new StringBuilder();
                    foreach (var node in linkNodes)
                    {
                        sb.AppendLine(node.Attributes["href"].Value);
                    }

                    return (sb.ToString() ,true);
                }
                catch (Exception ex)
                {
                    return ("解析错误:" + ex.Message,false);
                }
            }
            else
            {
                return ("获取不到匹配的链接",false);
            }
        }

    }
}
